package com.ebuildy.datavisualization
{
	import flash.geom.Point;
	import flash.utils.Dictionary;
	
	import mx.collections.ICollectionView;
	import mx.containers.Canvas;
	import mx.controls.Label;
	import mx.controls.treeClasses.ITreeDataDescriptor;
	import mx.core.ClassFactory;
	import mx.core.IDataRenderer;
	import mx.core.UIComponent;
	import mx.events.ResizeEvent;

	public class OrgChart extends Canvas
	{
		public var itemWidth:uint = 50;
		public var itemHeight:uint = 200;
		public var itemRenderer:ClassFactory = new ClassFactory(Label);
		
		private var map:Dictionary = new Dictionary(true);		
		
		public function OrgChart()
		{
			super();
			
			this.addEventListener(ResizeEvent.RESIZE,onResize);
		}
		
		private function onResize(e:ResizeEvent):void
		{
			this.validateChart();
		}
		
		public function validateChart():void
		{
			if (data)
			{
				var firstItem:ICollectionView = (data as ITreeDataDescriptor).getChildren(null);
				
				this.graphics.clear();
				this.graphics.lineStyle(1);
				
				renderItem(firstItem[0],1,0,0,this.width);
			}
		}
		
		private function renderItem(item:Object,length:uint , level:uint, offsetx:uint,w:uint):Point
		{
			var child:UIComponent = this.getItem(item);
			
			trace ('Level = ' + level + ': l=' + length + ',offset=' + offsetx + ',width=' + w);
				
			child.move(offsetx + w/2 - this.itemWidth/2,(this.itemHeight + 10)*level);
									
			var children:ICollectionView = (data as ITreeDataDescriptor).getChildren(item);
			var i:uint = 0;
			
			for each (item in children)
			{
				var pt:Point = this.renderItem(item,children.length,level + 1,offsetx + i*w/children.length,w/children.length);
				
				this.graphics.moveTo(child.x + this.itemHeight/2,child.y + this.itemHeight/2);
				this.graphics.lineTo(pt.x + this.itemWidth/2,pt.y + this.itemHeight/2);
				
				i ++;
			}
			
			return new Point(child.x,child.y);			
		}
		
		private function getItem(data:Object):UIComponent
		{
			if (this.map[data])
			{
				return this.map[data];
			}
			else
			{
				var buffer:IDataRenderer = this.itemRenderer.newInstance();
				
				buffer.data = data;
				
				this.map[data] = buffer;
				this.addChild(buffer as UIComponent);
					
				return buffer as UIComponent;
			}
		}
		
	}
}